package cn.tedu.micro.demo.rabbitmq;

import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import lombok.extern.slf4j.Slf4j;
import org.junit.Before;
import org.junit.Test;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

/**
 * 作为测试生产发送存在的测试类
 */
@Slf4j
public class MyProducer {
    private Channel channel;
    /**
     * @Before注解 junit提供的功能 作用是在所有@Test方法执行之前 执行,一般是初始化功能
     */
    @Before
    public void createChannel(){
        try{
            //1.创建连接工厂-工厂模式 创建连接的过程 被工厂封装了
            ConnectionFactory factory = new ConnectionFactory();
            //2.给工厂提供连接创建的必要属性
            //2.1rabbitmq host
            factory.setHost("192.168.8.100");
            //2.2rabbitmq port
            factory.setPort(5672);
            //2.3账号权限
            factory.setUsername("admin");
            factory.setPassword("123456");
            //3.生成一个长连接
            Connection connection = factory.newConnection();
            //4.创建通道短链接
            channel = connection.createChannel();
        }catch (Exception e){
            log.error("创建连接失败");
        }
    }

    //声明组件 队列组件
    @Test
    public void queueDeclare(){
        try {
            /**
             *String queue: 创建的队列名称,在虚拟主机中 只能存在唯一名称
             *Boolean durable: 队列是否持久化 true在rabbitmq重启之后 队列保持存在 false不存在
             *Boolean exclusive: 队列是绑定当前连接对象(独占 专属) true别的链接无法操作队列 false所有连接都可以操作队列
             *Boolean autoDelete: 队列是否自动删除 true队列从第一个监听消费者开始计算,到最后一个消费者断开连接,自动删除 false不删除
             *Map<String,Object> args: 队列特性参数 value三种 string (long double integer) boolean
             *key值是固定的,可以表示rabbitmq声明队列的特性,比如队列最大长度(最多可以容纳多少个消息)
            */
            Map<String,Object> args=new HashMap<>();
            args.put("name","王翠花");
            channel.queueDeclare("queue1",false,false,false,args);
        } catch (IOException e) {
            log.error("创建队列失败",e);
        }
    }
    //发送生产消息
    @Test
    public void sendMessage(){
        try{
            //1.准备发送消息的消息体数据,需要将消息体做序列化.
            String message="hello rabbitmq 你好,我是王翠花";
            byte[] body = message.getBytes();
            //2.调用channel的api方法 将消息发送
            /**
             * String exchange: 交换机名称,空字符串表示默认交换机
             * String routingKey: 路由键,交换机可以根据路由键值,计算对应的队列 转发消息
             * BasicProperties props: 消息属性. 比如消息优先级priority appId userId 关联
             * byte[] boyd: 消息体 消息内容
             */
            channel.basicPublish("biz_ex","北京",null,body);
            log.info("发送消息成功");
        }catch (Exception e){
            log.error("发送消息失败",e);
        }
    }
}
